// Copyright 2022 a.o.smith ALL Rights Reserved
package com.liuxinlong.modules.butler.service.impl;

import com.liuxinlong.common.AosException;
import com.liuxinlong.common.ExcelData;
import com.liuxinlong.common.ExcelImportCallBack;
import com.liuxinlong.common.ExcelImportService;
import com.liuxinlong.common.ImportResp;
import com.liuxinlong.common.RowError;
import com.liuxinlong.common.SnowFlake;
import com.liuxinlong.constant.ThreadLocalConstants;
import com.liuxinlong.constant.TimeFormatConstants;
import com.liuxinlong.enums.ButlerFaqTypeEnum;
import com.liuxinlong.enums.ReturnCodes;
import com.liuxinlong.modules.butler.service.FaqService;
import com.liuxinlong.modules.dao.FileManageDao;
import com.liuxinlong.modules.dao.QuestionAnswerDao;
import com.liuxinlong.modules.dao.UserBrowseRecordDao;
import com.liuxinlong.modules.dao.UserDao;
import com.liuxinlong.modules.entity.BrowseRecord;
import com.liuxinlong.modules.entity.QuestionAnswer;
import com.liuxinlong.modules.entity.User;
import com.liuxinlong.modules.system.service.FileManageService;
import com.liuxinlong.utils.ExcelUtils;
import com.liuxinlong.utils.ObjectUtils;
import com.liuxinlong.utils.ThreadlocalUtils;
import com.liuxinlong.utils.TimeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Q&A业务接口层实现
 *
 * @author liuxinlong@hotwater.com.cn
 * @version 1.0.0
 * @since 2022-10-09
 */
@Service
@Slf4j
public class FaqServiceImpl implements FaqService {

    @Autowired
    private QuestionAnswerDao questionAnswerDao;

    @Autowired
    private ExcelImportService excelImportService;

    @Autowired
    private FileManageService fileManageService;

    @Autowired
    private UserDao userDao;

    @Autowired
    private FileManageDao fileManageDao;

    @Autowired
    private UserBrowseRecordDao userBrowseRecordDao;

    @Override
    public List<Map<String, Object>> pageQuestionAnswer(Map<String, Object> queryParam) {
        List<QuestionAnswer> originalList = questionAnswerDao.pageQuestionAnswer(queryParam);
        List<Map<String, Object>> resultList = new ArrayList<>(originalList.size());
        Map<String, Map<String, String>> userMap = userDao.getUserMap();
//        String fileIds = StringUtils.strip(originalList.stream().map(QuestionAnswer::getAttach).collect(Collectors.toSet()).toString().replaceAll(" ", "").replaceAll(",null", "").replaceAll(",,", ","), "[]");
//
//        Set<String> fileIdList = new HashSet<>(Arrays.asList(fileIds.trim().split(",")));
//        Map<String, Map<String, Object>> fileMap = new HashMap<>();
//        if (!ObjectUtils.isEmpty(fileIdList)) {
//            fileMap = fileManageDao.getFileMapByIds(fileIdList);
//        }
//        String currentIp = "";
//        try {
//            InetAddress inetAddress = InetAddress.getLocalHost();
//            currentIp = inetAddress.getHostAddress();
//        } catch (Exception e) {
//            throw new AosException(ReturnCodes.HTTP_SYSTEM_ERROR, "系统异常");
//        }
        int startNum = (int) queryParam.get("startNum");
        int sort = startNum + 1;
        for (QuestionAnswer answer : originalList) {
            Map<String, Object> item = ObjectUtils.object2Map(answer);
            item.put("sort", sort);
            resultList.add(item);
            String createUser = answer.getCreateUser();
            String createUserName = userMap.containsKey(createUser) ? userMap.get(createUser).get("name") : "";
            item.put("createUserName", createUserName);
            String updateUser = answer.getUpdateUser();
            String updateUserName = userMap.containsKey(updateUser) ? userMap.get(updateUser).get("name") : "";
            item.put("updateUserName", updateUserName);
            item.put("subTypeName", answer.getSubType() > 0 ? ButlerFaqTypeEnum.getNameByValue(answer.getSubType()) : "-");
//            if (StringUtils.isNotEmpty(answer.getAttach())) {
//                List<String> attachFileList = Arrays.asList(answer.getAttach().split(","));
//                List<Map<String, Object>> fileList = new ArrayList<>(attachFileList.size());
//                int fileSort = 1;
//                for (String fileId : attachFileList) {
//                    if (!fileMap.containsKey(fileId.trim())) {
//                        continue;
//                    }
//                    Map<String, Object> fileInfo = new HashMap<>();
//                    fileInfo.put("sort", fileSort);
//                    fileInfo.put("id", fileId.trim());
//                    fileInfo.put("path", String.valueOf(fileMap.get(fileId.trim()).get("path")).replace("upload", "http:\\\\" + currentIp + ":8090\\preview\\upload"));
//                    fileList.add(fileInfo);
//                    fileSort++;
//                }
//                item.put("attachList", fileList);
//            }
            sort++;
        }
        return resultList;
    }

    @Override
    public int getQuestionAnswerCount(Map<String, Object> queryParam) {
        return questionAnswerDao.getQuestionAnswerCount(queryParam);
    }

    @Override
    public void addQuestionAnswer(QuestionAnswer questionAnswer, int forceFlag) {
        int showIndex = questionAnswer.getShowIndex();
        if (showIndex != 9999) {
            QuestionAnswer indexData = questionAnswerDao.selectByIndex(showIndex);
            if (!ObjectUtils.isEmpty(indexData) && !StringUtils.equals(questionAnswer.getId(), indexData.getId())) {
                if (forceFlag == 0) {
                    throw new AosException(ReturnCodes.HTTP_SAME_SERIAL_NUMBER, "当前排序位置已存在数据！");
                }
                indexData.setShowIndex(9999);
                questionAnswerDao.updateById(indexData);
            }
        }
        questionAnswer.setId(SnowFlake.nextIdStr());
        User currentUser = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        questionAnswer.setCreateUser(currentUser.getId());
        questionAnswerDao.insert(questionAnswer);
        String attach = questionAnswer.getAttach();
        if (StringUtils.isEmpty(attach)) {
            return;
        }
        fileManageService.updateBusinessFile(attach, questionAnswer.getId());
    }

    @Override
    public void updateQuestionAnswer(QuestionAnswer questionAnswer, int forceFlag) {
        QuestionAnswer oldDb = questionAnswerDao.selectById(questionAnswer.getId());
        int showIndex = questionAnswer.getShowIndex();
        if (showIndex != 9999) {
            QuestionAnswer indexData = questionAnswerDao.selectByIndex(showIndex);
            if (!ObjectUtils.isEmpty(indexData) && !StringUtils.equals(questionAnswer.getId(), indexData.getId())) {
                if (forceFlag == 0) {
                    throw new AosException(ReturnCodes.HTTP_SAME_SERIAL_NUMBER, "当前排序位置已存在数据！");
                }
                indexData.setShowIndex(9999);
                questionAnswerDao.updateById(indexData);
            }
        }
        User currentUser = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        questionAnswer.setCreateUser(oldDb.getCreateUser());
        questionAnswer.setCreateTime(oldDb.getCreateTime());
        questionAnswer.setUpdateUser(currentUser.getId());
        questionAnswer.setHeat(oldDb.getHeat());
        questionAnswerDao.updateById(questionAnswer);
        String attach = questionAnswer.getAttach();
//        if (StringUtils.isEmpty(attach)) {
//            return;
//        }
        fileManageService.updateBusinessFile(attach, questionAnswer.getId());
    }

    @Override
    public void deleteQuestionAnswer(String id) {
        questionAnswerDao.deleteById(id);
    }

    @Override
    public void exportQuestionAnswer(String id, HttpServletResponse response) {
        ExcelData data = new ExcelData();
        data.setFileName("FAQ导出excel.xlsx");
        Map<String, Object> queryParam = new HashMap<>();
        queryParam.put("startNum", 0);
        queryParam.put("pageSize", 10000);
        List<QuestionAnswer> questionAnswerList = questionAnswerDao.pageQuestionAnswer(queryParam);
        Map<String,Map<String,String>> userMap = userDao.getUserMap();
        String[] head = {"展示排序", "Question", "Answer", "主讲人/分享人", "时间"};
        data.setHead(head);
        String[][] dataList = new String[questionAnswerList.size()][head.length];
        int index = 0;
        for (QuestionAnswer questionAnswer : questionAnswerList) {
            dataList[index][0] = String.valueOf(questionAnswer.getShowIndex());
            dataList[index][1] = questionAnswer.getQuestion();
            dataList[index][2] = questionAnswer.getAnswer();
            dataList[index][3] = userMap.containsKey(questionAnswer.getCreateUser()) ? userMap.get(questionAnswer.getCreateUser()).get("name") : "";
            dataList[index][4] = StringUtils.isEmpty(questionAnswer.getUpdateTime()) ? questionAnswer.getCreateTime() : questionAnswer.getUpdateTime();

            index++;
        }
        data.setData(Arrays.asList(dataList));
        ExcelUtils.exportExcel(response, data);
    }

    @Override
    public ImportResp importQuestionAnswers(String fileName) {
        String filePath = fileName;
        return excelImportService.excelFile(filePath, 2, new ExcelImportCallBack() {
            @Override
            public Collection<RowError> checkRow(String[] record) {
                return checkRecordValid(record);
            }

            @Override
            public boolean persistRowToDb(String[] record) {
                QuestionAnswer questionAnswer = covertToBean(record);
                return false;
//				try {
//					materialStandardDao.insert(mocDetail);
//					return true;
//				} catch (Exception e) {
//					return false;
//				}
            }

            @Override
            public ImportResp partFailure(ImportResp resp) {
                resp.setRetCode(ReturnCodes.HTTP_SUCCESS.getRetCode());
                resp.setRetMessage("导入Q&A数据部分失败，总数=" + resp.getTotal() + ",失败总数=" + resp.getFailedTotal());
                return resp;
            }

            @Override
            public ImportResp allSuccess(ImportResp resp) {
                resp.setRetMessage("导入Q&A数据全部成功，总数=" + resp.getTotal());
                return resp;
            }

            @Override
            public List<Map> convertFailList(List<String[]> failRecords) {
                List<Map> list = new ArrayList<>();
                int sort = 1;
                for (String[] failRecord : failRecords) {
                    Map item = new HashMap();
                    item.put("sort", sort);
                    item.put("question", failRecord[1]);
                    item.put("answer", failRecord[2]);
                    list.add(item);
                    sort++;
                }
                return list;
            }

        });
    }

    @Override
    public ImportResp batchAddQuestionAnswer(List<QuestionAnswer> dataList) {
//        Map<String, Map<String, String>> standardSnMap = questionAnswerDao.getStandardSnMap();
        User currentUser = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        List<Map> failedList = new ArrayList<>();
        boolean insertSuccess;
        int sort = 1;
        for (QuestionAnswer questionAnswer : dataList) {
            String message = "";
//            if (standardSnMap.size() > 0 && standardSnMap.containsKey(standard.getStandardSn())) {
//                message = "标准编号已存在";
//                insertSuccess = false;
//            } else {
            String id = SnowFlake.nextIdStr();
            questionAnswer.setId(id);
            questionAnswer.setCreateUser(currentUser.getId());
            try {
                questionAnswerDao.insert(questionAnswer);
                insertSuccess = true;
            } catch (Exception e) {
                insertSuccess = false;
                message = e.getMessage();
            }
//            }
            if (!insertSuccess) {
                Map<String, Object> map = ObjectUtils.object2Map(questionAnswer);
                map.put("sort", sort);
                map.put("message", message);
                sort++;
                failedList.add(map);
            }
        }
        ImportResp resp = new ImportResp();
        resp.setRetCode(failedList.size() > 0 ? ReturnCodes.HTTP_IMPORT_PART_FAIL.getRetCode() : ReturnCodes.HTTP_SUCCESS.getRetCode());
        resp.setFailedList(failedList);
        resp.setRetMessage(failedList.size() > 0 ? "导入Q&A信息部分成功" : "导入Q&A信息成功");
        return resp;
    }

    @Override
    public void countClick(String id) {
        QuestionAnswer questionAnswer = questionAnswerDao.selectById(id);
        if (ObjectUtils.isEmpty(questionAnswer)) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "Q&A信息不存在！");
        }
        User currentUser = (User) ThreadlocalUtils.getCache(ThreadLocalConstants.USER_INFO);
        String currentTime = TimeUtils.getDate(TimeFormatConstants.YYYY_MM_DD_HH_MM_SS);
        String currentDate = currentTime.substring(0, 10);
        BrowseRecord browseRecord = userBrowseRecordDao.getUserBrowseRecord(id, currentUser.getId(), currentDate);
        if (!ObjectUtils.isEmpty(browseRecord)) {
            log.info("用户当日已点击，不统计浏览量");
            return;
        }
        questionAnswer.setHeat(questionAnswer.getHeat() + 1);
        questionAnswerDao.updateById(questionAnswer);
        BrowseRecord newBrowseRecord = new BrowseRecord();
        newBrowseRecord.setId(SnowFlake.nextIdStr());
        newBrowseRecord.setBusinessId(id);
        newBrowseRecord.setBrowseUser(currentUser.getId());
        newBrowseRecord.setBrowseTime(currentTime);
        userBrowseRecordDao.insert(newBrowseRecord);
    }

    @Override
    public Map<String, Object> queryFaqInfo(String id) {
        QuestionAnswer questionAnswer = questionAnswerDao.selectById(id);
        return ObjectUtils.object2Map(questionAnswer);
    }

    /**
     * 转换数据为入库数据
     *
     * @param record 数据记录
     * @return 入库数据
     */
    private QuestionAnswer covertToBean(String[] record) {
        QuestionAnswer questionAnswer = new QuestionAnswer();
        questionAnswer.setQuestion(record[1].trim());
        questionAnswer.setAnswer(record[2].trim());
        questionAnswer.setShowIndex(Integer.parseInt(record[3].trim()));
        return questionAnswer;

    }

    /**
     * 校验参数合法性
     *
     * @param record 导入数据
     * @return 参数合法性
     */
    private Collection<RowError> checkRecordValid(String[] record) {
        List<RowError> rowErrors = new ArrayList<>();
        if (StringUtils.isEmpty(record[1].trim())) {
            addRowError("设计编号不能为空", rowErrors);
        } else {
            if (record[1].trim().length() > 20) {
                addRowError("设计编号长度不能超过20", rowErrors);
            }
        }
        if (StringUtils.isEmpty(record[2].trim())) {
            addRowError("设计名称不能为空", rowErrors);
        } else {
            if (record[2].trim().length() > 100) {
                addRowError("设计名称长度不能超过100", rowErrors);
            }
        }
        if (StringUtils.isEmpty(record[2].trim())) {
            addRowError("兼容性不能为空", rowErrors);
        } else {

            if (record[2].trim().length() > 100) {
                addRowError("兼容性字段非法", rowErrors);
            }
        }
        if (StringUtils.isEmpty(record[4].trim())) {
            addRowError("回顾部门不能为空", rowErrors);
        } else {
            if (record[4].trim().length() > 20) {
                addRowError("回顾部门长度不能超过20", rowErrors);
            }
        }
        return rowErrors;
    }

    /**
     * 添加错误行数据
     *
     * @param errorMessage 错误信息
     * @param rowErrors    错误行数据
     */
    private void addRowError(String errorMessage, List<RowError> rowErrors) {
        RowError rowError = new RowError(errorMessage);
        rowErrors.add(rowError);
    }

}
